package com.hongxun.design.utils.socketutil;

import android.os.Handler;
import android.widget.TextView;

import com.hongxun.design.MyApp;
import com.hongxun.design.bean.ProjectItemBean;
import com.hongxun.design.bean.service.MessageData;
import com.hongxun.design.mytools.MString;
import com.hongxun.design.mytools.MyLog;
import com.hongxun.design.mytools.ToastShow;
import com.hongxun.design.object_properties.MyMessage;
import com.hongxun.design.utils.RegularUtil;
import com.hongxun.design.utils.fastjson.FastJsonUtil;
import com.hongxun.design.utils.fastjson.MergeUtil;
import com.hongxun.design.utils.fileutil.GetFileUtil;
import com.hongxun.design.utils.fileutil.SetFileUtil;
import com.hongxun.design.utils.fileutil.ZipUtil;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;


/**
 * Created by zerdoor_pc on 2016/4/20.
 */
public class ReciveAndSend {
    private static TextView text;

    public static MessageData getMessageData(int dataType, String msg, String name) {
        return new MessageData(dataType, msg, name);
    }


    /**
     * 接收服务器消息*
     */
    public static void reciveMsg(InputStream in) throws IOException {

        DataInputStream dins = new DataInputStream(in);
        int DataType = dins.readInt();
        MyLog.L(MString.service + "  DataType：" + DataType);
        long FileSizeLen = dins.readLong();
        MyLog.L(MString.service + "  FileSizeLen：" + FileSizeLen);
        int msgLength;
        String name = null;
        switch (DataType) {
            case 0:
                byte[] data1 = new byte[(int) FileSizeLen];
                dins.readFully(data1);
                MyLog.L(MString.service + "  msgLength：" + new String(data1));
                break;
            case 1:
                break;
            case 2:
                break;
            case 3:
                msgLength = dins.readInt();
                MyLog.L(MString.service + "  msgLength2：" + msgLength);
                byte[] data = new byte[msgLength];
                dins.readFully(data);
                MyLog.L(MString.service + "  name：" + new String(data));
                name = new String(data);
                // String savePath = Environment.getExternalStorageDirectory().getPath() + "/" + name;
                MyLog.L(MString.service + ": savename=" + name);
                saveBitmap(in, name, FileSizeLen, null);
                break;

        }

    }

    /**
     * 接收服务器消息*
     */
    public static String reciveMsg(InputStream in, int DataType, Handler handler) throws IOException {
        DataInputStream dins = new DataInputStream(in);
//        long FileSizeLen = dins.readLong();
        long FileSizeLen = dins.readInt();
        MyLog.L(MString.service + "  FileSizeLen：" + FileSizeLen);
        int msgLength;
        String name = null;
        String s = "-1";
        switch (DataType) {
            case 1:
                byte[] data1 = new byte[(int) FileSizeLen];
                dins.readFully(data1);
                s = new String(data1);
                MyLog.L(MString.service + "  msgLength：" + s);
                break;
            case 2:
                break;
            case 3:
                break;
            case 4:
                msgLength = dins.readInt();
                MyLog.L(MString.service + "  msgLength2：" + msgLength);
                byte[] data = new byte[msgLength];
                dins.readFully(data);
                name = new String(data);//读取文件名
                MyLog.L(MString.service + "  name：" + name);
                //String savePath = MyApp.File.getSDPath(name);//存储路径
                MyLog.L(MString.service + ": savename=" + name);
                saveBitmap(in, name, FileSizeLen, handler);
                break;

        }
        return s;
    }

    /**
     * 接收服务器消息*
     */
    public static String reciveMsg(InputStream in, int DataType) throws IOException {

        DataInputStream dins = new DataInputStream(in);
        long FileSizeLen = dins.readLong();
        MyLog.L(MString.service + "  FileSizeLen：" + FileSizeLen);
        int msgLength;
        String name = null;
        String s = "-1";
        switch (DataType) {
            case 1:
                byte[] data1 = new byte[(int) FileSizeLen];
                dins.readFully(data1);
                s = new String(data1);
                MyLog.L(MString.service + "  msgLength：" + s);
                break;
            case 2:
                break;
            case 3:
                break;
            case 4:
                msgLength = dins.readInt();
                MyLog.L(MString.service + "  msgLength2：" + msgLength);
                byte[] data = new byte[msgLength];
                dins.readFully(data);
                name = new String(data);//读取文件名
                MyLog.L(MString.service + "  name：" + name);
                // String savePath = MyApp.File.getSDPath(name);//存储路径
                MyLog.L(MString.service + ": savename=" + name);
                saveBitmap(in, name, FileSizeLen, null);
                break;

        }
        return s;
    }

    /**
     * 存储 *
     */
    public static void saveBitmap(InputStream in, String name, long FileSizeLen, Handler handler) {
        MyLog.L(MString.service + " name=" + name);//name=ProjectStage_4822.zip

        if (name.length() == 0) {
            if (handler != null) handler.sendMessage(MyMessage.getMessage(200, -1, -1, "0"));
            ToastShow.showShort(MyApp.activity, "文件名为空！");
            return;
        }
//        String path=  MyApp.File.getCachaPath() +"FaceFile/"+name;
        String path = MyApp.File.getCachaPath() + name;
        File f = new File(path);
        if (!f.exists()) {
            MyLog.L(MString.service + ": exists");
            f.delete();
        }
        MyLog.L(MString.service + ":no exists");
        FileOutputStream fOut = null;
        try {
            f.createNewFile();
            fOut = new FileOutputStream(f);
            byte[] buffer = new byte[1024];
            int size = -1;
            long length = 0;

            MyLog.L(MString.service + "存储 " + in.available());
            long item = 0;
            if (in.available() != 0) {
                item =in.available();
            }
            MyLog.L(MString.service2 + "读取消息循环开始" + in.available());
            while ((size = in.read(buffer)) != -1) {
//                if (in.available() != 0) {
                length += size;
                MyLog.L(MString.service2 + "dsfsdf122 length==" + length+" size="+size+" FileSizeLen="+FileSizeLen);
                if (handler != null) {
                    float code= ((float)((length*1.0)/FileSizeLen));
                    if (code>=1)code= (float) 0.99;
                    MyLog.L(MString.service2 + "dsfsdf (int) (code*100)==" + (int) (code*100)+" code="+code+" FileSizeLen="+FileSizeLen);
                    handler.sendMessage(MyMessage.getMessage(200, 0, (int) (code*100), FileSizeLen + ""));
                }

                try {
                    fOut.write(buffer, 0, size);
                } catch (Exception e) {
                    MyLog.L(MString.service2 + "读取消息循环异常:no exists" + e.toString());
                }
                //MyLog.L(MString.service + size + "  buffer=" + new String(buffer, 0, size));
//                } else {
//                    break;
//                }

            }

            MyLog.L(MString.service2 + "读取消息循环结束" + in.available());
            fOut.flush();

            MyLog.L(MString.service2 + "存储完毕" + in.available());
        } catch (IOException e1) {
            MyLog.L(MString.service2 + "读取消息循环异常:no exists" + e1.toString());
            e1.printStackTrace();
        } finally {
            try {
                if (fOut != null)
                    fOut.close();
            } catch (IOException e) {
                MyLog.L(MString.service2 + "读取消息循环完毕:no2 exists" + e.toString());
                e.printStackTrace();
            }
        }
        if (handler != null) {
            handler.sendMessage(MyMessage.getMessage(200, -1, 100, "100"));
        }
        try {
             ZipUtil.upZipFile(path, MyApp.File.getSDPath(MyApp.openIdent), false);//缓存到SD卡
//            ZipUtil.upZipFile(path, MyApp.File.getSystemPath(MyApp.openIdent), false);//缓存到系统

            String zipUPstring= MyApp.File.getCachaPath() + "FaceFile";
            File desDir = new File(zipUPstring);
            if (desDir.exists()){
                MyApp.File.delete(desDir);
            }
            ZipUtil.upZipFile(path,zipUPstring, false);//缓存到临时文件夹
            String code = "[^_]+_(\\d+)\\.zip";
            String id = "";
            Matcher matcher = RegularUtil.getMatcher(code, name);
            if (matcher.matches()) {
                id = matcher.group(1);
                MyLog.L(MString.SUCCESSED + " body1=" + id);
            }
            if (id == null || id.length() == 0) {
                id = name.replace("ProjectStage_", "").replace(".zip", "");
            }

            String oldId=getStageIdByUUID(id);//(id应变为实际的ID)
            String cachePath = MyApp.File.getSystemPath(MyApp.openIdent + File.separator + MString.Project_ + oldId);//缓存路径
            String loadPath = MyApp.File.getSystemPath(MyApp.openIdent + File.separator + MString.Request + File.separator + MString.Project_ + oldId);//同步缓存路径

            String getcache = MyApp.File.getCachaPath() + "/FaceFile/" + MString.Project_ + id + File.separator + MString.Response ;//本地
            String getload = MyApp.File.getCachaPath() + "/FaceFile/" + MString.Project_ + id + File.separator + MString.Request ;//上传

            File file = new File(cachePath);
            File fileload = new File(loadPath);
            if (!file.exists()||(file.listFiles().length==0&&fileload.listFiles().length==0)) {
                if (fileload.exists()) {
                    fileload.delete();
                }
                //直接移动
                MyLog.L("直接移动::"+getcache+"\n"+cachePath);
                MyLog.L("直接移动::"+getload+"\n"+loadPath);
                MyApp.File.copyFolder(getcache, cachePath);
                MyApp.File.copyFolder(getload, loadPath);//复制
            } else {//合并
                //合并文件
               // MString.ProjectStageExplorePointList 点位
                //MString.ProjectTransformerList 台区
                //MString.ProjectExplorePointInfoPhoto 照片
                //MString.ProjectExploreAcrossOnChannelList 跨越点
                String oldlistNamePath11=File.separator+MString.ProjectStageExplorePointList + "_" +oldId + "_" + 11 + SetFileUtil.addEnd();
                String oldlistNamePath12=File.separator+MString.ProjectStageExplorePointList + "_" +oldId + "_" + 12 + SetFileUtil.addEnd();

                String listNamePath11=File.separator+MString.ProjectStageExplorePointList + "_" +id + "_" + 11 + SetFileUtil.addEnd();
                String listNamePath12=File.separator+MString.ProjectStageExplorePointList + "_" +id + "_" + 12 + SetFileUtil.addEnd();
                if (fileload.exists()) {//合并上传文件夹点位列表
                    MyLog.L("合并上传文件夹点位列表::"+getload+listNamePath11+"\n"+loadPath+oldlistNamePath11);
                    MyLog.L("合并上传文件夹点位列表::"+getload+listNamePath12+"\n"+loadPath+oldlistNamePath12);

                    copyCoverFolder(getload+listNamePath11, loadPath+oldlistNamePath11,getload,loadPath);
                    copyCoverFolder(getload+listNamePath12, loadPath+oldlistNamePath12,getload,loadPath);
//                    MyApp.File.copyCoverFolder(getload, loadPath);//覆盖复制
                    if (id.equals(oldId)){
                        //覆盖项目基本信息
                        copyOfNotPoint(getload,loadPath,id);
                    }
                    //合并文件
                }else{
                    MyApp.File.copyFolder(getload, loadPath);//复制上传文件
                }
                //合并文件夹点位列表
                MyLog.L("合并上传文件夹点位列表::"+getcache+listNamePath11+"\n"+cachePath+oldlistNamePath11);
                MyLog.L("合并上传文件夹点位列表::"+getcache+listNamePath12+"\n"+cachePath+oldlistNamePath12);
                copyCoverFolder(getcache+listNamePath11, cachePath+oldlistNamePath11,getcache,cachePath);
                copyCoverFolder(getcache+listNamePath12, cachePath+oldlistNamePath12,getcache,cachePath);

                //合并非点位列表（台区）
                //.../


                if (id.equals(oldId)){
                    //覆盖项目基本信息
                    copyOfNotPoint(getcache,cachePath,id);
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**遍历本地项目文件列表如果UUID存在则判断有无stageid，有则返回Stageid，否则返回UUID**/
    private static String getStageIdByUUID(String uuid){
        String json = MyApp.File.ReadFileData(MString.ProjectStageListFile + GetFileUtil.addEnd());//获取缓存项目列表
        List<ProjectItemBean> Data = new ArrayList<>();
        if (GetFileUtil.check(json)) {
            Data.addAll(FastJsonUtil.JsonToGetProjectListBean(json));
        }

        for (ProjectItemBean b : Data) {
            if (b.getUUID().equals(uuid)){
                if ( b.getStage_id()!=null&&!b.getStage_id().equals(MString.code_zero)&& b.getStage_id().length()>0){
                    return b.getStage_id();
                }
            }
        }
        return uuid;
    }
    /**覆盖非点位文件**/
    private static  void copyOfNotPoint(String rootnewPath, String rootoldPath,String uuid){
        //覆盖项目基本信息
         MyApp.File.copyFile(rootnewPath+"/"+MString.ProjectStageBaseInfo+"_"+uuid,rootoldPath+"/"+MString.ProjectStageBaseInfo+"_"+uuid);
         MyApp.File.copyFile(rootnewPath+"/"+MString.ProjectTransformerListFile + "_" + uuid,rootoldPath+"/"+MString.ProjectTransformerListFile+"_"+uuid);
    }

    private static void copyCoverFolder(String newPath, String oldPath,String rootnewPath, String rootoldPath){
        //比较点位列表
        MergeUtil.ExplorationList(newPath,oldPath ,  rootnewPath,   rootoldPath);
    }
    /**
     * 向服务器发送消息*
     */
    public static void sendTextMsg(OutputStream outs, MessageData data) {
        String msg = data.getMsg();
        String name = data.getName();
        int type = data.getDataType();
        MyLog.L(MString.service + ": msg=" + msg);
        MyLog.L(MString.service + ": name=" + name);
        MyLog.L(MString.service + ": type=" + type);
        DataOutputStream out = new DataOutputStream(outs);
        try {
            switch (type) {
                case 0:
                    sendText(out, msg);
                    break;
                case 1:
                    sendImage(out, msg);
                    break;
                case 2:
                    sendVoice(out, msg);
                    break;
                case 3:
                    if (name.length() != 0) {
                        sendFile(out, msg, name);
                    } else {
                        MyLog.L(MString.service + "文件名不能为空");
                    }
                    break;
            }
//            out.flush();
//            outs.flush();

            out.close();
//            outs.close();
        } catch (IOException e) {
            MyLog.L(MString.service + ":IOException2 " + e.toString());
        }
    }

    private static void sendText(DataOutputStream out, String msg) throws IOException {
        MyLog.L(MString.service + ": sendText");
        out.writeInt(0);
        out.writeLong(msg.getBytes().length);
        out.write(msg.getBytes());
        out.flush();
    }

    private static void sendImage(DataOutputStream out, String path) throws IOException {
        MyLog.L(MString.service + ": sendImage");
        out.writeInt(1);
        FileInputStream fileInput = new FileInputStream(path);
        out.writeLong(fileInput.available());
        int size = -1;
        byte[] buffer = new byte[1024];
        while ((size = fileInput.read(buffer, 0, 1024)) != -1) {
            out.write(buffer, 0, size);
        }
        out.flush();
    }

    private static void sendVoice(DataOutputStream out, String path) throws IOException {
        MyLog.L(MString.service + ": sendVoice");
        out.writeInt(2);
        FileInputStream fileInput = new FileInputStream(path);
        out.writeLong(fileInput.available());
        int size = -1;
        byte[] buffer = new byte[1024];
        while ((size = fileInput.read(buffer, 0, 1024)) != -1) {
            out.write(buffer, 0, size);
        }
        out.flush();
    }

    private static void sendFile(DataOutputStream out, String path, String name) throws IOException {
        MyLog.L(MString.service + ": sendFile" + out.size());
        out.writeInt(3);//文件类型


        FileInputStream fileInput = new FileInputStream(path);
        out.writeLong(fileInput.available());//文件长度


        out.writeInt(name.getBytes().length);//文件名长度


        out.write(name.getBytes());

        int size = -1;
        byte[] buffer = new byte[1024];
        while ((size = fileInput.read(buffer, 0, 1024)) != -1) {
            out.write(buffer, 0, size);
        }

        out.flush();
        MyLog.L(MString.service + ":end" + out.size());

    }
}
